<!--
 * @Author: C.
 * @Date: 2023-12-12 14:15:14
-->
<template>
  <view class="m-form-warpper">
    <TnForm
      ref="formRef"
      :model="formModel"
      :rules="getRules"
      label-position="top"
    >
      <template v-for="schema in getSchema" :key="schema.field">
        <FormItem
          :form-model="formModel"
          :schema="schema"
          :set-form-model="setFormModel"
        />
      </template>
    </TnForm>
  </view>
</template>
<script lang="ts" setup>
import { computed, onMounted, reactive, ref, unref, watch } from 'vue'
import TnForm from '@tuniao/tnui-vue3-uniapp/components/form/src/form.vue'
import FormItem from './components/form-item.vue'
import type { FormRules, TnFormInstance } from '@tuniao/tnui-vue3-uniapp'
import { isNullOrUnDef } from '@/utils/is'

const props = defineProps({
  schemas: {
    type: Array as PropType<Recordable[]>,
    default: () => [],
  },
})
const emits = defineEmits(['register', 'field-value-change'])
// 表单数据
const formModel = reactive<Recordable>({})

const formRef = ref<TnFormInstance>()
const propsRef = ref<Recordable>()
const isInitedDefaultRef = ref(false)
const defaultValueRef = ref<Recordable>({})

const getProps = computed(() => {
  return { ...props, ...unref(propsRef) }
})
function setProps(props: Recordable) {
  propsRef.value = { ...unref(propsRef), ...props }
}

const getSchema = computed(() => {
  return unref(getProps).schemas
})
// 规则
const getRules = computed(() => {
  const rules: Recordable = {}
  unref(getProps).schemas.forEach((item) => {
    if (item.rules) {
      rules[item.field] = item.rules
    }
  })
  return rules
})
// 初始化默认值
watch(
  () => getSchema.value,
  () => {
    if (unref(isInitedDefaultRef)) {
      return
    }
    initDetault()
    isInitedDefaultRef.value = true
  }
)
function initDetault() {
  if (unref(getSchema)?.length) {
    const obj: Recordable = {}
    unref(getSchema).forEach((item) => {
      const { defaultValue } = item
      if (!isNullOrUnDef(defaultValue)) {
        obj[item.field] = defaultValue

        if (formModel[item.field] === undefined) {
          formModel[item.field] = defaultValue
        }
      }
    })
    defaultValueRef.value = obj
  }
}
/* 提交表单 */
const validate = async () => {
  const bool = await formRef.value?.validate()
  if (bool) {
    return formModel
  }
}
function resetForm() {
  formRef.value?.resetFields()
  setFieldsValue(defaultValueRef.value)
  // formModel.value = { ...defaultValueRef.value }
}
// 下级组件赋值
function setFormModel(key: string, value: any) {
  formModel[key] = value
  emits('field-value-change', key, value)
}
function setFieldsValue(model: Recordable) {
  const fields = unref(getSchema)
    .map((item) => item.field)
    .filter(Boolean)
  fields.forEach((key) => {
    if (Reflect.has(model, key)) {
      formModel[key] = model[key]
    }
  })
}
function getFieldsValue() {
  return formModel
}
onMounted(() => {
  emits('register', {
    type: 'mounted',
    setProps,
    validate,
    reset: resetForm,
    setFieldsValue,
    getFieldsValue,
  })
})
</script>

<style lang="scss" scoped>
.m-form-warpper {
  /* padding: 15rpx; */
}
</style>
